﻿namespace ConsoleApp;

public class DemoCopy
{
    public class Person : ICloneable
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public List<string> Tags { get; set; } // 引用类型
 
        public Person ShallowCopy()
        {
            return (Person)this.MemberwiseClone(); // 浅拷贝
        }
        
        public object Clone()
        {
            // 深拷贝：手动创建新对象并复制所有字段
            return new Person
            {
                Name = Name,
                Age = Age,
                Tags = [..Tags] // 新建 List
            };
        }
    }

    public record PersonRecord
    {
        public string Name { get; init; }
        public int Age { get; init; }
        public List<string> Tags { get; init; }
    }
    
    public struct Point
    {
        public int X { get; set; }
        public int Y { get; set; }
    }
    
    /// <summary>
    /// 浅拷贝（Shallow Copy）浅拷贝会复制对象的值类型字段和引用类型字段的引用（不复制引用指向的对象）。
    /// </summary>
    public void ShallowCopy()
    {
        var original = new Person
        {
            Name = "Alice",
            Age = 25,
            Tags = ["Developer", "C#"]
        };
        
        // 方法 1：使用 MemberwiseClone()
        var copied = original.ShallowCopy();
 
        // 修改 copied 的引用类型会影响 original
        copied.Tags.Add("New Tag"); // original.Tags 也会被修改！
        
        // 方法 2：使用 { ... } 对象初始化器
        var copied1 = new Person
        {
            Name = original.Name,
            Age = original.Age,
            Tags = original.Tags // 仍然是引用复制
        };
    }

    /// <summary>
    /// 深拷贝（Deep Copy）深拷贝会复制所有字段，包括引用类型指向的对象。
    /// </summary>
    public void DeepCopy()
    {
        var original = new Person
        {
            Name = "Alice",
            Age = 25,
            Tags = ["Developer", "C#"]
        };
        
        // 方法 1: 手动实现 ICloneable 接口
        var copied = (Person)original.Clone();
        copied.Tags.Add("New Tag"); // original.Tags 不受影响
        
        // 方法 2：使用序列化（如 JsonConvert 或 System.Text.Json）
        //var json = JsonSerializer.Serialize(obj);
        //return JsonSerializer.Deserialize<T>(json);
        
        // 方法 3：使用 AutoMapper
        
        
        // 方法 4：使用 record 类型
        // 使用 with 表达式（浅拷贝，但可以手动深拷贝引用类型）
        var originalRecord = new PersonRecord
        {
            Name = "Alice",
            Age = 25,
            Tags = ["Developer", "C#"]
        };
        var copied1 = originalRecord with { Tags = [..original.Tags] };

        // 方法 5：结构体（Struct）的拷贝(struct 是值类型，赋值时会自动深拷贝)
        var p1 = new Point { X = 1, Y = 2 };
        var p2 = p1; // 自动深拷贝
        p2.X = 10;   // p1.X 仍然是 1
        
        // 使用 System.Memory 的 Span<T> 或 Memory<T>（高性能场景）（如数组、结构体数组）
        var source = new int[] { 1, 2, 3 };
        var destination = new int[source.Length];
        source.CopyTo((Span<int>)destination); // 类似深拷贝
    }
}

